package com.sheledon.flyCat.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.reflections.Reflections;
import org.reflections.scanners.TypeAnnotationsScanner;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * @author sheledon
 */
@Slf4j
public class ReflectionUtils {
    public static Set<Class<?>> scanAnnotationClass(String [] packageNames, Class<? extends Annotation> annotation) {
        Reflections reflections = new Reflections(packageNames,new TypeAnnotationsScanner());
        Set<Class<?>> annotatedClass = reflections.getTypesAnnotatedWith(annotation, true);
        log.info("load Annotation {} , Class: [{}]",annotation,annotatedClass);
        return annotatedClass;
    }
    public static <T> Set<Class<? extends T>> scanSubClass(String[] packageNames,Class<T> clazz){
        try{
            Reflections reflections = new Reflections(packageNames);
            return reflections.getSubTypesOf(clazz);
        }catch (Exception e){ }
        return new HashSet<>();
    }
    public static Object newInstance(Class<?> clazz){
        try {
            return clazz.newInstance();
        } catch (InstantiationException | IllegalAccessException e) { }
        return null;
    }
    public static Object newInstance(Constructor<?> constructor,Object... args){
        try {
            return constructor.newInstance(args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    public static void setFiledValue(Field field,Object obj,Object value){
        try {
            field.set(obj,value);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    public static Object executeMethod(Method method,Object target,Object[] args){
        try {
            method.setAccessible(true);
            return method.invoke(target,args);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }
}
